using UnityEngine;
using System.Collections;

/// <summary>
/// This class represents all moving actors and serves as a base for the playercontroller as well as the enemies
/// </summary>
[RequireComponent(typeof(CharacterController))]
[RequireComponent(typeof(Animation))]
public class ActorController : MonoBehaviour
{

    #region Public Fields
    public float Speed = 8f;
    public float JumpForce = 1f;

    // Animations
    public AnimationClip IdleAnimation;
    public AnimationClip WalkAnimation;

    /// <summary>
    /// Is used to change the speed of ALL Actors working with this component for slowmow-like effects
    /// </summary>
    public static float SlowMotionModifier = 1f;

    public bool IsIdling { get { return _move.x == 0 && _move.y == 0; } }
    public bool IsWalking { get { return _move.x != 0; } }
    public bool IsFalling { get { return _move.y < 0; } }
    public bool IsJumping { get { return _move.y > 0; } }
    #endregion

    #region Private Fields
    protected CharacterController _charController;
    protected Vector3 _move;
    protected bool _affectedByGravity = true;

    private float _currentJumpForce;
    private float _fallAcceleration = 1f;
    #endregion

    #region Protected Fields
    protected const float ANIMATION_FADE_LENGTH = 0.2f;
    #endregion

    protected void Start() 
    {
        _charController = GetComponent<CharacterController>();
        if (_charController == null) Debug.LogError("Charcontroller not attached!");
	}

	protected void Update () 
    {
        // Add jump force
        if (_currentJumpForce > 0)
        {
            _move.y += _currentJumpForce;
            _currentJumpForce -= Time.deltaTime;
        }

        // Apply gravity
        if (_affectedByGravity && !_charController.isGrounded)
        {
            _move.y += Physics.gravity.y * Time.deltaTime * _fallAcceleration;
            _fallAcceleration += 0.1f;
        }
        else
        {
            // Reset acceleration
            _fallAcceleration = 1f;
        }
        _charController.Move(_move);

        UpdateAnimation();
	}

    /// <summary>
    /// Play standard animations
    /// </summary>
    protected void UpdateAnimation()
    {
        if (this.IsWalking)
        {
            animation.CrossFade(WalkAnimation.name, ANIMATION_FADE_LENGTH);
        }
        else
        {
            animation.CrossFade(IdleAnimation.name, ANIMATION_FADE_LENGTH);
        }
    }

    public void Jump()
    {
        _currentJumpForce = JumpForce;
    }

}
